package com.liukaixin.product.ru.data.repositories;

import android.content.Context;
import android.support.annotation.NonNull;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.liukaixin.product.ru.AppController;
import com.liukaixin.product.ru.data.CallBackListener;
import com.liukaixin.product.ru.data.model.Favorite;
import com.liukaixin.product.ru.data.model.Result;
import com.liukaixin.product.ru.data.model.User;
import com.liukaixin.product.ru.data.model.UserPush;
import com.liukaixin.product.ru.enumerate.ResultTypeEnum;
import com.liukaixin.product.ru.service.CompetitionService;
import com.liukaixin.product.ru.service.ServiceFactory;
import com.liukaixin.product.ru.service.UserService;
import com.liukaixin.product.ru.util.ACache;
import com.orhanobut.logger.Logger;

import java.util.List;

import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Created by liukaixin on 16/9/3.
 */

public class UserRepository {

    private static UserRepository INSTANCE = null;

    private UserService userService;

    private ACache aCache = AppController.getInstance().getCache();

    private boolean isCacheDirty = false;

    // Prevent direct instantiation.
    private UserRepository() {

        this.userService = ServiceFactory
                .createRetrofitService(UserService.class,
                        ServiceFactory.BASE_URL);
    }

    public static UserRepository getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new UserRepository();
        }
        return INSTANCE;
    }

    /**
     * 登录.
     *
     * @param user     用户
     * @param callback 回调
     */
    public void login(@NonNull User user,
                      @NonNull
                      final CallBackListener<User> callback) {

        checkNotNull(user);
        checkNotNull(callback);

        userService.login(user)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Result<User>>() {
                    @Override
                    public void onCompleted() {
                        callback.onCompleted();
                    }

                    @Override
                    public void onError(Throwable e) {
                        Logger.e(e, e.getMessage());
                        callback.onError(e.getMessage());
                    }

                    @Override
                    public void onNext(Result<User> result) {
                        if (result.getCode().equals(ResultTypeEnum.SUCCESS.getValue())) {
                            aCache.put("user",
                                    JSON.toJSONString(result.getBean()));
                            Logger.d("登录后取回来的user = %s", result.getBean().toString());
                            callback.onNext(result.getBean());
                        } else {
                            callback.onError(result.getMessage());
                        }
                    }
                });
    }

    /**
     * 注册.
     *
     * @param user     用户
     * @param callback 回调
     */
    public void register(@NonNull final User user,
                         @NonNull
                         final CallBackListener<String> callback) {
        checkNotNull(user);
        checkNotNull(callback);

        userService.register(user)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Result<User>>() {
                    @Override
                    public void onCompleted() {
                        callback.onCompleted();
                    }

                    @Override
                    public void onError(Throwable e) {
                        callback.onError(e.getMessage());
                    }

                    @Override
                    public void onNext(Result<User> userResult) {
                        if (userResult.getCode().equals(Result.SUCCESS)) {
                            aCache.put("user",
                                    JSON.toJSONString(userResult.getBean()));
                            callback.onNext(userResult.getMessage());
                        } else {
                            callback.onError(userResult.getMessage());
                        }
                    }
                });
    }

    /**
     * 根据用户id获取用户信息
     *
     * @param userId   用户id
     * @param callback 回调
     */
    public void getUserInfoById(@NonNull Integer userId,
                                @NonNull
                                final CallBackListener<User> callback) {
        checkNotNull(userId);
        checkNotNull(callback);

        userService.getUserInfoById(userId)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Result<User>>() {
                    @Override
                    public void onCompleted() {
                        callback.onCompleted();
                    }

                    @Override
                    public void onError(Throwable e) {
                        callback.onError(e.getMessage());
                    }

                    @Override
                    public void onNext(Result<User> result) {
                        if (result.getCode().equals(Result.SUCCESS)) {
                            callback.onNext(result.getBean());
                            aCache.put("user",
                                    JSON.toJSONString(result.getBean()));
                            isCacheDirty = false;
                        } else {
                            callback.onError(result.getMessage());
                        }
                    }
                });

    }

    /**
     * 更新用户.
     *
     * @param user     用户
     * @param callback 回调
     */
    public void updateUser(@NonNull User user,
                           @NonNull
                           final CallBackListener<String> callback) {
        checkNotNull(user);
        checkNotNull(callback);

        userService.updateUser(user)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Result<String>>() {
                    @Override
                    public void onCompleted() {
                        callback.onCompleted();
                    }

                    @Override
                    public void onError(Throwable e) {
                        callback.onError(e.getMessage());
                    }

                    @Override
                    public void onNext(Result<String> result) {
                        if (result.getCode().equals(Result.SUCCESS)) {
                            aCache.put("user",
                                    JSON.toJSONString(user));
                            callback.onNext(ResultTypeEnum.SUCCESS.getDescription());
                        } else {
                            callback.onError(result.getMessage());
                        }
                    }
                });
    }

    public void favorite(@NonNull Favorite favorite,
                         @NonNull
                         final CallBackListener<Result<String>> callback) {
        checkNotNull(favorite);
        checkNotNull(callback);

        userService.favorite(favorite)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Result<String>>() {
                    @Override
                    public void onCompleted() {
                        callback.onCompleted();
                    }

                    @Override
                    public void onError(Throwable e) {
                        callback.onError(e.getMessage());
                    }

                    @Override
                    public void onNext(Result<String> result) {
                        callback.onNext(result);
                    }
                });

    }

    public void getFavoriteStatusByStarIdAndUserId(@NonNull Integer starId,
                                                   @NonNull Integer userId,
                                                   @NonNull
                                                   final
                                                   CallBackListener<Boolean> callback) {
        checkNotNull(starId);
        checkNotNull(callback);

        userService.getFavoriteOrNotByCompIdAndUserId(starId, userId)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Result<Boolean>>() {
                    @Override
                    public void onCompleted() {
                        callback.onCompleted();
                    }

                    @Override
                    public void onError(Throwable e) {
                        callback.onError(e.getMessage());
                    }

                    @Override
                    public void onNext(Result<Boolean> result) {
                        callback.onNext(result.getBean());
                    }
                });
    }

    public void cancelFavorite(@NonNull Integer starId,
                               @NonNull Integer userId,
                               @NonNull CallBackListener<Result<String>> callback) {
        checkNotNull(starId);
        checkNotNull(userId);
        checkNotNull(callback);

        userService.cancelFavorite(starId, userId)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Result<String>>() {
                    @Override
                    public void onCompleted() {
                        callback.onCompleted();
                    }

                    @Override
                    public void onError(Throwable e) {
                        Logger.e(e, e.getMessage());
                        callback.onError(e.getMessage());
                    }

                    @Override
                    public void onNext(Result<String> result) {
                        callback.onNext(result);
                    }
                });
    }

    public void addClientId(@NonNull String clientId,
                            @NonNull CallBackListener<Integer> callback) {
        checkNotNull(clientId);
        checkNotNull(callback);

        User user = JSON.parseObject(AppController.getInstance().getCache().getAsString("user"),
                User.class);
        UserPush userPush = new UserPush();
        userPush.setUserId(user.getId());
        userPush.setClientId(clientId);
        userService.addClientId(userPush)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Result<Integer>>() {
                    @Override
                    public void onCompleted() {
                        callback.onCompleted();
                    }

                    @Override
                    public void onError(Throwable e) {
                        callback.onError(e.getMessage());
                    }

                    @Override
                    public void onNext(Result<Integer> result) {
                        callback.onNext(result.getBean());
                    }
                });
    }
}
